/*
this program is used to send msg to trigger the ele machine operation
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>

#include <sys/stat.h>
#include <fcntl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include "../app/can_uim.h"
#include "../app/msg_def.h"

#define FILE_NAME "ele_ctl.txt"

//#define msgQueueKeyPath "/home/usr/msg/msg.tmp"
//#define FILE_NAME "uim_cmd.txt"

#define ACT_SID(sid) (((sid&0x1f)<<6)+2)
#define ACT_EID(sid,tcw) (((sid&0x60)<<8) + tcw)

// typedef struct _msg_can_frame
// {
//     long type;
//     struct can_frame canFrame;
// }msg_can_frame;

// typedef enum
// {
//    RET_BACK,
//    MOVE,
//    STOP,
//    QUERY,
// }OPCODE;

// typedef struct _ctl_uim
// {
//     unsigned char sid;
//     unsigned char opcode;
//     unsigned char dir;
//     unsigned char reserved;
//     unsigned int position;
//     unsigned int queryParam;
// }ctl_uim;


// typedef struct _msg_ctl_uim
// {
//     long type;
//     ctl_uim ctlFrame;
// }msg_ctl_uim;

int main(int argc, char *argv[])
{
    FILE * fp;
    unsigned char sid = 0;
    unsigned char tcw = 0;
    int flag_file = 0;
    int dlc_f = 0;
    unsigned char data_f[8];

    struct can_frame canFrame;

    msg_ctl_uim ctlFrame;

    memset(&ctlFrame,0,sizeof(msg_ctl_uim));

    msg_can_frame msgFrame;

    int flagValid = 0;

    if(argc<2)
    {
        fp = fopen(FILE_NAME,"r");
        

    }
    else
    {
        fp = fopen(argv[1],"r");
    }
    if(fp!=NULL)
    {
        char StrLine[256];
        char * tmpPtr = NULL;
        while(!feof(fp))
        {
           memset(StrLine,0,256);
           fgets(StrLine,256,fp);
           if(strstr(StrLine,"sid"))
           {
               tmpPtr = StrLine+4;
               sid = atoi(tmpPtr);
               flag_file = 1;
               ctlFrame.ctlFrame.sid = sid;
           }

           if(strstr(StrLine,"tcw"))
           {
               tmpPtr = StrLine+4;
               tcw = atoi(tmpPtr);
           }

           int i1 = 0;
           if(strstr(StrLine,"data"))
           {
               int lenLeft  = strlen(StrLine);
               
               char strOneData[8];
               tmpPtr = StrLine+5;
               lenLeft -= 5;
               while(lenLeft>=4)
               {
                   memset(strOneData,0,8);
                   memcpy(strOneData,tmpPtr,4);
                   data_f[i1++] = strtoul(strOneData,NULL,0);
                   tmpPtr+=5;
                   lenLeft-=5;
               }
               dlc_f = i1;
           }
           if(strstr(StrLine,"type"))
           {
                
                tmpPtr = StrLine + 5;
                if(strstr(tmpPtr,"uim"))
                {
                   ctlFrame.type = 1;
                   flagValid |= 0x01;
                }
                else if(strstr(tmpPtr,"lec"))
                {
                   ctlFrame.type = 2;
                   flagValid |= 0x01;
                }
                else
                {
                    /* code */
                    flagValid &= 0xfe;
                }
                

           }

           if(strstr(StrLine,"op"))
           {
               int tempCode = atoi(StrLine+3);
               if((tempCode>=RET_BACK)&&(tempCode<=QUERY))
               {
                   ctlFrame.ctlFrame.opcode = tempCode;
                   if(tempCode==MOVE)
                   {
                       flagValid |= 0x04;
                   }
                   else
                   {
                       flagValid |= 0x02;
                   }
               }
               else
               {
                   /* code */
                   break;
               }
               
           }

           if(strstr(StrLine,"dir"))
           {
               int tmpDir = atoi(StrLine+4);
               if((tmpDir>=0)&&(tmpDir<=1))
               {
                   ctlFrame.ctlFrame.un_cmd.moveCtl.dir = tmpDir;
                   flagValid |= 0x08;
               }
               else
               {
                   /* code */
                   flagValid &= 0xf7;
                   break;
               }
           }

           if(strstr(StrLine,"pos"))
           {
               int tmpDis = atoi(StrLine+4);
               ctlFrame.ctlFrame.un_cmd.moveCtl.position = tmpDis;
               flagValid |= 0x10;
           }

           if(strstr(StrLine,"eleNum"))
           {
               int tmpNum = atoi(StrLine+7);
               ctlFrame.ctlFrame.un_cmd.moveCtl.ele_index = tmpNum;
               flagValid |= 0x20;
           }

           

           if(strstr(StrLine,"inc_speed"))
           {
               int tmpNum = atoi(StrLine+10);
               ctlFrame.ctlFrame.un_cmd.moveCtl.inc_speed = tmpNum;
               continue;
               //flagValid |= 0x20;
           }
           if(strstr(StrLine,"dec_speed"))
           {
               int tmpNum = atoi(StrLine+10);
               ctlFrame.ctlFrame.un_cmd.moveCtl.dec_speed = tmpNum;
               continue;
               //flagValid |= 0x20;
           }

           if(strstr(StrLine,"speed"))
           {
               int tmpNum = atoi(StrLine+6);
               ctlFrame.ctlFrame.un_cmd.moveCtl.speed = tmpNum;
               continue;
               //flagValid |= 0x20;
           }
           

        }
        
        

         printf("param from file: sid:%d,tcw:%d,dlc_f:%d\n",sid,tcw,dlc_f);
         printf("speed:%d,inc_speed:%d,dec_speed:%d\n",
         ctlFrame.ctlFrame.un_cmd.moveCtl.speed,
         ctlFrame.ctlFrame.un_cmd.moveCtl.inc_speed,
         ctlFrame.ctlFrame.un_cmd.moveCtl.dec_speed);
        // char strPrint[128];
        // int n=0, n1=0;
        // memset(strPrint,0,128);
        // if(dlc_f)
        // {
        //    n = snprintf(strPrint,128,"%02x ",data_f[0]);
        //    for(int i=1;i<dlc_f;i++)
        //    {
        //        n1 = snprintf(strPrint+n,128-n,"%02x ",data_f[i]);
        //        n += n1;
        //    }
        //    printf("data:%s\n",strPrint);        

        // }
        
    }
    else
    {
        /* code */
        printf("open file failed\n");
    }

    key_t key = ftok(msgQueueKeyPath, 0x1234);
    if(key < 0)
    {
        perror("ftok");
        printf("%s\n",msgQueueKeyPath);
        return -1;
    }

    int msg_id = msgget(key, IPC_CREAT|0600);//IPC_CREAT|0600
    if(msg_id < 0)
    {
        perror("msgget");
        return -1;
    }

    msgFrame.type = 1;

    msgFrame.frame.can_id = (ACT_SID(sid)<<18) + ACT_EID(sid,tcw);
    msgFrame.frame.can_id &= CAN_EFF_MASK;
	msgFrame.frame.can_id |= CAN_EFF_FLAG;
    msgFrame.frame.can_dlc = dlc_f>8?8:dlc_f;

    //memcpy(canFrame.data,data_f,canFrame.can_dlc);

    
    // ctlFrame.type = 1;
    // ctlFrame.ctlFrame.opcode = MOVE;
    // ctlFrame.ctlFrame.sid = sid;
    // ctlFrame.ctlFrame.dir = 1;
    // ctlFrame.ctlFrame.position = 2000;
    //memcpy(msgFrame.mtext,&canFrame,sizeof(struct can_frame));

    //if(msgsnd(msg_id, (void*)&msgFrame, sizeof(struct can_frame), 0) < 0)
    //{
    //    perror("msgsnd");
    //    return -1;
    //}
    
    if((flagValid & 0x03 == 0x03)   /*here is for opcode not move*/
      ||(flagValid & 0x1d == 0x1d)) /*here is for opcode move*/
    {
        if(msgsnd(msg_id, (void*)&ctlFrame, sizeof(ctl_uim), 0) < 0)
        {
            perror("msgsnd");
            return -1;
        }
        else
        {
            /* code */
            printf("msg send success,type is %d,opcode[%d]\n",ctlFrame.type,ctlFrame.ctlFrame.opcode);
        }
        
    }
    else
    {
        /* code */
        printf("flag is %02x\n",flagValid);
    }
       
    
    //msgctl(msg_id,IPC_RMID,NULL);

    return 0;
} 
/*
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <time.h>

#define TEXT_SIZE 512

struct _msgbuf
{

    long mtype;
    int status;
    char time[20];
    char mtext[TEXT_SIZE];    
};

char *getxtsj()
{
    time_t tv;
    struct tm *tmp;
    static char buf[20];

    tv = time( 0 );

    tmp = localtime(&tv);

    sprintf(buf,"%02d:%02d:%02d",tmp->tm_hour , tmp->tm_min,tmp->tm_sec);
    return buf;
}

int main(int argc, char **argv)

{

    int msqid ;

struct msqid_ds info;

struct _msgbuf buf;

struct _msgbuf buf1;

int flag ;

int sendlength, recvlength ;

int key ;



key = ftok("msg.tmp", 0x01 ) ;

if ( key < 0 )

{

perror("ftok key error") ;

return -1 ;

}



msqid = msgget( key, 0600|IPC_CREAT ) ;

if ( msqid < 0 )

{

 perror("create message queue error") ;
return -1 ;

}



buf.mtype = 1;

buf.status = 9;

strcpy(buf.time, getxtsj()) ;

strcpy(buf.mtext, "happy new year!\n") ;

sendlength = sizeof(struct msgbuf) - sizeof(long) ;

flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

if ( flag < 0 )

{

perror("send message error") ;

return -1 ;

}

buf.mtype = 3 ;

buf.status = 9 ;

strcpy(buf.time, getxtsj()) ;

strcpy(buf.mtext, "good bye!") ;

sendlength = sizeof(struct msgbuf) - sizeof(long) ;

flag = msgsnd( msqid, &buf, sendlength , 0 ) ;

if ( flag < 0 )

{

perror("send message error") ;

return -1 ;

}
system("ipcs -q") ;

return 0 ;

}*/